package com.albert.java_log4j_demo;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 *
 * cankao :https://blog.csdn.net/worm0527/article/details/69939307
 * @author 陈晖
 * @version 1.0
 * @date 2021/9/9 21:04
 */


public class BytesHexStrTranslate {

    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * 字节数组转换为16进制的字符串
     * @param bytes 字节数组
     * @return 16进制字符串
     */
    public static String bytesToHexFun2(byte[] bytes) {
        char[] buf = new char[bytes.length * 2];
        int index = 0;
        // 利用位运算进行转换，可以看作方法一的变种
        for(byte b : bytes) {
            buf[index++] = HEX_CHAR[b >>> 4 & 0xf];
            buf[index++] = HEX_CHAR[b & 0xf];
        }

        return new String(buf);
    }
    public static byte[] getHexByte (byte[] bytes) {
        char[] buf = new char[bytes.length * 2];
        int index = 0;
        // 利用位运算进行转换，可以看作方法一的变种
        for(byte b : bytes) {
            buf[index++] = HEX_CHAR[b >>> 4 & 0xf];
            buf[index++] = HEX_CHAR[b & 0xf];
        }

        char[] chars = buf;

        Charset cs = Charset.forName ("GBK");

        CharBuffer cb = CharBuffer.allocate (chars.length);

        cb.put (chars);

        cb.flip ();

        ByteBuffer bb = cs.encode (cb);

        byte[] ddfd= bb.array();
        return ddfd;

    }


    /**
     *  十六进制字符串转换为java的字符串
     * @param str
     * @return
     */
    public static byte[] toBytes(String str) {
        if(str == null || str.trim().equals("")) {
            return new byte[0];
        }

        byte[] bytes = new byte[str.length() / 2];
        for(int i = 0; i < str.length() / 2; i++) {
            String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }

        return bytes;
    }

    /**
     * 16进制直接转换成为字符串(无需Unicode解码)
     * @param hexStr
     * @return
     */
    public  static  String hexStr2Str(String hexStr) {
        String str =  "0123456789ABCDEF" ;
        char [] hexs = hexStr.toCharArray();
        byte [] bytes =  new  byte [hexStr.length() /  2 ];
        int  n;
        for  ( int  i =  0 ; i < bytes.length; i++) {
            n = str.indexOf(hexs[ 2  * i]) *  16 ;
            n += str.indexOf(hexs[ 2  * i +  1 ]);
            bytes[i] = ( byte ) (n &  0xff );
        }
        return  new  String(bytes);
    }


    /**
     * int to byte
     * @param val
     * @return
     */
    public byte[] intToByte(int val){
        byte[] b = new byte[4];
        b[0] = (byte)(val & 0xff);
        b[1] = (byte)((val >> 8) & 0xff);
        b[2] = (byte)((val >> 16) & 0xff);
        b[3] = (byte)((val >> 24) & 0xff);
        return b;
    }

    /**
     * int到byte[] 由高位到低位
     * @param i 需要转换为byte数组的整行值。
     * @return byte数组
     */
    public static byte[] intToByteArray(int i) {
        byte[] result = new byte[4];
        result[0] = (byte)((i >> 24) & 0xFF);
        result[1] = (byte)((i >> 16) & 0xFF);
        result[2] = (byte)((i >> 8) & 0xFF);
        result[3] = (byte)(i & 0xFF);
        return result;
    }

    /**
     * byte[]转int
     * @param bytes 需要转换成int的数组
     * @return int值
     */
    public static int byteArrayToInt(byte[] bytes) {
        int value=0;
        for(int i = 0; i < 4; i++) {
            int shift= (3-i) * 8;
            value +=(bytes[i] & 0xFF) << shift;
        }
        return value;
    }


    /**
     * 【java】十六进制字符串转化为字节数组
     * https://blog.csdn.net/jjlovefj/article/details/81775094
     * @param s
     * @return
     */
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

    /**
     * 将16进制字符串转换为byte数组
     * @param hexItr 16进制字符串
     * @return
     */
    public static byte[] hexItr2Arr(String hexItr) throws DecoderException {
        return Hex.decodeHex(hexItr);
    }


    public static void main(String[] args) throws Exception {
        byte[] bytes = "欢迎光临".getBytes("GBK");
        System.out.println("欢迎光临".length());
        System.out.println(bytes.length);
        System.out.println("字节数组为：" + Arrays.toString(bytes));
        System.out.println("方法二：bytesToHexFun2------>" + bytesToHexFun2(bytes));


        System.out.println("==================================");

        String str = "bbb6d3adb9e2c1d9";
        System.out.println(new String(toBytes(str), "GBK"));

        String lend = "cda3b3b5cab1b3a43132d0a1cab13330b7d6";
        System.out.println(new String(toBytes(lend), "GBK"));


        String line4 = "c7ebbdc9b7d13130d4aa";
        System.out.println(new String(toBytes(line4), "GBK"));

        // 十六进制 字符串
        String voice = "c8ebb3a1cab1bce4323032312d30392d31312032313a3038";
        System.out.println(new String(toBytes(voice),"GBK"));

        // 字符串先转为GBK编码的字节数组，然后再用字符数组转换为16进制的字符串
        String str2 = "请缴费10元";
        System.out.println(bytesToHexFun2(str2.getBytes("GBK")));


        System.out.println(getHexByte(str2.getBytes("GBK")));

        // 16进制字节数据
        byte[] hexBytearray = getHexByte(str2.getBytes("GBK"));

//        String hexString = bytesToHexFun2(str2.getBytes("GBK"));
//        System.out.println(hexStringToByteArray(hexString));
//        byte[] bytearray = hexItr2Arr(hexString);
//        System.out.println(bytearray);
    }
}
